package top.lingkang.finalgateway.admin.controller;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import org.noear.snack.ONode;
import org.noear.solon.annotation.Controller;
import org.noear.solon.annotation.Inject;
import org.noear.solon.annotation.Mapping;
import org.noear.solon.core.handle.MethodType;
import top.lingkang.finalgateway.FinalGateway;
import top.lingkang.finalgateway.admin.constants.LogType;
import top.lingkang.finalgateway.admin.dto.ResponseResult;
import top.lingkang.finalgateway.admin.dto.ResponseResultPage;
import top.lingkang.finalgateway.admin.entity.IpListEntity;
import top.lingkang.finalgateway.admin.entity.IpListLogEntity;
import top.lingkang.finalgateway.admin.mapper.ActionLogMapper;
import top.lingkang.finalgateway.admin.mapper.IpListLogMapper;
import top.lingkang.finalgateway.admin.mapper.IpListMapper;
import top.lingkang.finalgateway.admin.param.IpListEditParam;
import top.lingkang.finalgateway.admin.param.IpListLogParam;
import top.lingkang.finalgateway.admin.param.IpListParam;
import top.lingkang.finalgateway.utils.CommonUtils;
import top.lingkang.finalvalidated.core.ValidObject;
import top.lingkang.mm.page.PageHelper;
import top.lingkang.mm.page.PageInfo;
import top.lingkang.mm.solon.Transactional;

import java.util.List;

/**
 * @author lingkang
 * @create by 2024/5/17 15:13
 */
@Controller
@Mapping("/api/ip")
public class IpListController {
    @Inject
    private IpListMapper ipListMapper;
    @Inject
    private ActionLogMapper actionLogMapper;
    @Inject
    private IpListLogMapper ipListLogMapper;

    @Mapping(value = "/list", method = MethodType.GET)
    public Object list(@ValidObject IpListParam param) {
        PageHelper.startPage(param.getPage(), param.getSize());
        List<IpListEntity> list = ipListMapper.list(param);
        PageInfo page = PageHelper.getPage();
        return new ResponseResultPage<>().setData(list)
                .setTotal(page.getTotal())
                .setPage(param.getPage())
                .setSize(param.getSize());
    }

    @Mapping(value = "/log", method = MethodType.GET)
    public Object log(@ValidObject IpListLogParam param) {
        PageHelper.startPage(param.getPage(), param.getSize());
        List<IpListLogEntity> list = ipListLogMapper.list(param);
        PageInfo page = PageHelper.getPage();
        return new ResponseResultPage<>().setData(list)
                .setTotal(page.getTotal())
                .setPage(param.getPage())
                .setSize(param.getSize());
    }

    @Transactional
    @Mapping(value = "/add", method = MethodType.POST)
    public Object add(@ValidObject IpListEditParam param) {
        if (StrUtil.isNotBlank(param.getWhite()))
            Assert.isTrue(CommonUtils.checkIpList(param.getWhite()), "白名单格式错误，请检查");
        if (StrUtil.isNotBlank(param.getBlack()))
            Assert.isTrue(CommonUtils.checkIpList(param.getBlack()), "黑名单格式错误，请检测");
        Assert.isFalse(ipListMapper.existsById(param.getPort()), "添加失败，端口配置已经存在");
        IpListEntity entity = new IpListEntity();
        entity.setPort(param.getPort());
        entity.setWhite(param.getWhite());
        entity.setBlack(param.getBlack());
        ipListMapper.insert(entity);
        actionLogMapper.addLog(LogType.iplist_add, ONode.load(param).toJson());
        // 清理黑白名单缓存
        FinalGateway.clearIpListCache(param.getPort());
        ipListLogMapper.add(param.getPort(), "用户添加", "添加黑白名单: " + param.getPort());
        return new ResponseResult<>().ok();
    }

    @Transactional
    @Mapping(value = "/update", method = MethodType.POST)
    public Object update(@ValidObject IpListEditParam param) {
        if (StrUtil.isNotBlank(param.getWhite()))
            Assert.isTrue(CommonUtils.checkIpList(param.getWhite()), "白名单格式错误，请检查");
        if (StrUtil.isNotBlank(param.getBlack()))
            Assert.isTrue(CommonUtils.checkIpList(param.getBlack()), "黑名单格式错误，请检测");
        IpListEntity entity = ipListMapper.selectById(param.getPort());
        Assert.notNull(entity, "更新失败，端口配置不存在");
        entity.setWhite(param.getWhite());
        entity.setBlack(param.getBlack());
        ipListMapper.updateById(entity);
        actionLogMapper.addLog(LogType.iplist_update, ONode.load(param).toJson());
        // 清理黑白名单缓存
        FinalGateway.clearIpListCache(param.getPort());
        ipListLogMapper.add(param.getPort(), "用户修改", "更新黑白名单: " + param.getPort());
        return new ResponseResult<>().ok();
    }

    @Transactional
    @Mapping(value = "/delete", method = MethodType.POST)
    public Object delete(Integer port) {
        Assert.notNull(ipListMapper.existsById(port), "删除失败，端口配置不存在");
        ipListMapper.deleteById(port);
        actionLogMapper.addLog(LogType.iplist_delete, String.valueOf(port));
        // 清理黑白名单缓存
        FinalGateway.clearIpListCache(port);
        ipListLogMapper.add(port, "用户删除", "删除黑白名单: " + port);
        return new ResponseResult<>().ok();
    }

    @Mapping(value = "/get", method = MethodType.GET)
    public Object get(Integer port) {
        IpListEntity entity = ipListMapper.selectById(port);
        return new ResponseResult<>().ok(entity);
    }

}
